<?php
/**
 * Created by PhpStorm.
 * User: ysk <yanshuaike171211@credithc.com>
 * Date: 2021/6/21
 * Time: 13:54
 */

namespace api\base;

/**
 * Class ResponseApi
 * @package api\base
 *
 * @SWG\Response(
 *     response="base.ResponseApi",
 *     description="the basic response",
 *     @SWG\Schema(
 *     required={"code","msg"},
 *         @SWG\Property(property="code",description="返回码",type="string",example="200"),
 *         @SWG\Property(property="msg",description="说明",type="string",example="ok"),
 *         @SWG\Property(property="data",description="数据",type="object",example={}),
 *         @SWG\Property(property="sub_code",description="二级返回码",type="string",example=""),
 *         @SWG\Property(property="sub_msg",description="二级返回说明",type="string",example="")
 *     )
 * )
 */


class ResponseApi {

    public $code;

    public $data;

    public $msg;

    public $sub_code;

    public $sub_msg;

    public $trace;

    private function __construct(
         $code,
         $msg,
         $data,
         $sub_code=null,
         $sub_msg=null
    )
    {

        $this->code = $code;
        $this->data = $data;
        $this->sub_code = $sub_code;
        $this->msg = $msg;
        if (empty($sub_msg)) {
            $sub_msg = $msg;
        }
        $this->sub_msg = $sub_msg;
    }


    public static function make(
        $data,
        $msg = 'OK',
        $sub_code = Null,
        $sub_msg = Null,
        $code = '200'
    ){
        return new static($code, $msg, $data, $sub_code, $sub_msg);
    }


    public static function succeed($data = '', $msg = 'OK')
    {
        return self::make($data, $msg, null, null, '200');
    }


    public static function fail($msg = 'OK',$sub_code,$sub_msg,$code='400')
    {
        return self::make(null, $msg, $sub_code, $sub_msg, $code);
    }



    /**
     * 发生异常
     *
     * @param \Throwable $exception
     * @param string     $msg
     * @param string     $code
     *
     * @return ResponseApi
     */
    public static function exception($exception, string $msg = '发生错误', string $code = '400')
    {
        $out_msg  = $msg;
        $out_code = $code;

        if (empty($msg)) {
            $out_msg = $exception->getMessage();
        }

        $sub_code = null;
        $sub_msg  = null;
        if ($exception instanceof ApiException) {
            $out_code = $exception->getCode();
            $sub_code  = $exception->sub_code;
            $sub_msg   = $exception->sub_msg;
        }

        $resp = self::fail($out_msg, $sub_msg, $sub_code, $out_code);

        // TODO 完善异常输出
        if (YII_DEBUG) {
            $resp->trace = $exception->getMessage() . ":\n"
                . $exception->getFile() . ':' . $exception->getLine() . "\n"
                . $exception->getTraceAsString();
        }

        return $resp;
    }

    /**
     * @param \Throwable $err
     *
     * @return ResponseApi
     */
    public static function error(\Throwable $err)
    {
        return self::exception($err, null, '500');
    }

    /**
     * 跳转
     *
     * @param string $url    地址
     * @param string $method 请求方法,GET,POST
     * @param array  $params 参数
     *
     * @return ResponseApi
     */
    public static function redirect(string $url, string $method = 'GET', array $params = [])
    {
        return new static('303', '跳转', ['url' => $url, 'method' => $method, 'params' => $params]);
    }


    public function __toString()
    {
        return json_encode($this);
    }

}
